package com.weixing.mall.provider.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weixing.mall.base.constant.GlobalConstant;
import com.weixing.mall.core.support.auth.SysAuth;
import com.weixing.mall.provider.api.model.vo.RoleVo;
import com.weixing.mall.provider.api.service.SysUserRpcService;
import com.weixing.mall.provider.mapper.AgentAccountMapper;
import com.weixing.mall.provider.mapper.AgentBonusMapper;
import com.weixing.mall.provider.mapper.AgentRebateMapper;
import com.weixing.mall.provider.mapper.AgentWithdrawMapper;
import com.weixing.mall.provider.model.domain.AgentAccount;
import com.weixing.mall.provider.model.domain.AgentBonus;
import com.weixing.mall.provider.model.domain.AgentRebate;
import com.weixing.mall.provider.model.domain.AgentWithdraw;
import com.weixing.mall.provider.model.dto.AgentWithdrawDto;
import com.weixing.mall.provider.model.enums.*;
import com.weixing.mall.provider.model.query.AgentWithdrawQuery;
import com.weixing.mall.provider.model.vo.*;
import com.weixing.mall.provider.service.IAgentAccountService;
import com.weixing.mall.provider.service.IAgentRebateService;
import com.weixing.mall.provider.service.IAgentWithdrawService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 代理商模块-代理商提现表 服务实现类
 * </p>
 *
 * @author Small
 * @since 2019-11-18
 */
@Service
public class AgentWithdrawServiceImpl extends ServiceImpl<AgentWithdrawMapper, AgentWithdraw> implements IAgentWithdrawService {

    @Autowired
    private AgentBonusMapper agentBonusMapper;

    @Autowired
    private AgentRebateMapper agentRebateMapper;

    @Autowired
    private IAgentRebateService  agentRebateService;
    @Autowired
    private IAgentAccountService agentAccountService;
    @Autowired
    private AgentAccountMapper agentAccountMapper;
    @Autowired
    private SysUserRpcService sysUserRpcService;

    @Override
    public IPage<AgentWithdrawVo> selectListOfPage(Page page, AgentWithdrawQuery agentWithdrawQuery, SysAuth auth) {
        if (auth != null) {
            Long uid = auth.getUid();
            List<RoleVo> list = sysUserRpcService.getRoleById(uid).getData();
            for (RoleVo vo : list) {
                if (vo.getRoleCode().equals(GlobalConstant.RoleCode.ADMIN)) {
                    return baseMapper.selectListOfPage(page, agentWithdrawQuery);
                }
            }
            for (RoleVo vo : list) {
                if (vo.getRoleCode().equals(GlobalConstant.RoleCode.KFADMIN)) {
                    return baseMapper.selectListOfPage(page, agentWithdrawQuery);
                }
            }
            agentWithdrawQuery.setCustomerId(uid.intValue());
            return baseMapper.selectListOfPage(page, agentWithdrawQuery);
        } else {
            return baseMapper.selectListOfPage(page, agentWithdrawQuery);
        }

    }

    @Override
    public AgentWithdrawSettleVo selectAgentSettle(Long id) {
        return baseMapper.selectAgentSettle(id);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void audit(Long id, AgentWithdrawAuditEnum auditResult, SysAuth sysAuth,String auditRemark) {
        //更新提现列表
        AgentWithdraw agentWithdraw = getById(id);
        agentWithdraw.setOperator(sysAuth.getUid());
        agentWithdraw.setAuditResult(auditResult.getValue());
        agentWithdraw.setAuditTime(new Date());
        agentWithdraw.setAuditRemark(auditRemark);
        baseMapper.updateById(agentWithdraw);
        //根据状态调整代理商账户信息表和代理商返利信息表
        if(auditResult.getValue().intValue()==AgentWithdrawAuditEnum.ADOPT.getValue()){//通过后可提现金额和返利信息表进行更新
            AgentAccount agentAccount=agentAccountService.findByAgentId(agentWithdraw.getAgentId());
            BigDecimal avaAmount=agentAccount.getAvaAmount().subtract(agentWithdraw.getAmount());
            agentAccount.setAvaAmount(avaAmount);
            agentAccountService.updateById(agentAccount);
            UpdateWrapper<AgentRebate> ew = new UpdateWrapper<>();
            ew.lambda().set(AgentRebate::getOperationId, sysAuth.getUid())
                    .set(AgentRebate::getOpertaionName, sysAuth.getRealName())
                    .set(AgentRebate::getOperationStatus, AgentWithdrawAuditEnum.ADOPT.getValue())
                    .set(AgentRebate::getOperationTime, LocalDate.now())
                    .eq(AgentRebate::getOutBillId,agentWithdraw.getId() )
                    .eq(AgentRebate::getAgentId,agentWithdraw.getAgentId());
            agentRebateService.update(ew);

        }else if(auditResult.getValue().intValue()==AgentWithdrawAuditEnum.REJECT.getValue()){
            UpdateWrapper<AgentRebate> ew = new UpdateWrapper<>();
            ew.lambda().set(AgentRebate::getOperationId, sysAuth.getUid())
                    .set(AgentRebate::getOpertaionName, sysAuth.getRealName())
                    .set(AgentRebate::getOperationStatus, AgentWithdrawAuditEnum.REJECT.getValue())
                    .set(AgentRebate::getOperationTime, LocalDate.now())
                    .set(AgentRebate::getOutBillId,null)
                    .eq(AgentRebate::getOutBillId,agentWithdraw.getId() )
                    .eq(AgentRebate::getAgentId,agentWithdraw.getAgentId());
            agentRebateService.update(ew);
        }


    }

    @Override
    public IPage selectAgentOrderList(Page initMpPage, Long agentId) {
        return null;
    }

    @Override
    public FrontAgentWithdrawSettleVo withdrawInfo(String currentTime, Long agentId) {
        Double withdrawAbleAmount = 0.0;
        Double withdrawAmount = 0.0;
        FrontAgentWithdrawSettleVo frontAgentWithdrawSettleVo = baseMapper.withdrawInfo(agentId);
        System.out.println(frontAgentWithdrawSettleVo);
        //查询未提现分红金额
        List<AgentBonus> bonusList = agentBonusMapper.withdrawBonus(agentId, currentTime);
        //查询未提现分红金额 ----  2020-3-20 18:16:50 商定分红不可提现
        /*List<AgentBonus> bonusList=agentBonusMapper.withdrawBonus(currentUserId,currentTime);
        for (AgentBonus agentBonus : bonusList) {
            if(agentBonus!=null){
                if(agentBonus.getIsEnable()==1){
                    withdrawAmount+=agentBonus.getBonusAmount().doubleValue();
                }
                withdrawAbleAmount+=agentBonus.getBonusAmount().doubleValue();
            }
        }
        //查询未体现返利金额
        List<AgentRebate> agentRebateList=agentRebateMapper.withdrawRebate(agentId,currentTime);
        }*/
        //查询未体现返利金额 ---- 2020-3-20 18:17:15 从新计算  判断可提现日期
        /*List<AgentRebate> agentRebateList=agentRebateMapper.withdrawRebate(currentUserId,currentTime);
        for (AgentRebate agentRebate : agentRebateList) {
           if(agentRebate!=null){
               if(agentRebate.getIsEnable()==1){
                   withdrawAmount+=agentRebate.getRebateAmount().doubleValue();
               }
               withdrawAbleAmount+=agentRebate.getRebateAmount().doubleValue();
           }
        }*/
        //提现额度
        withdrawAbleAmount = agentRebateMapper.selectWithdrawRebate(agentId, null).doubleValue();
        //可提现金额
        withdrawAmount = agentRebateMapper.selectWithdrawRebate(agentId, currentTime).doubleValue();
        if (frontAgentWithdrawSettleVo != null) {
            frontAgentWithdrawSettleVo.setWithdrawAmount(withdrawAmount);
            frontAgentWithdrawSettleVo.setWithdrawAbleAmount(withdrawAbleAmount);
            if (frontAgentWithdrawSettleVo.getWithdrawPwd() != null) {
                frontAgentWithdrawSettleVo.setWithdrawPwd(null);
                frontAgentWithdrawSettleVo.setWhether(WhetherEnum.YES);
            } else {
                frontAgentWithdrawSettleVo.setWhether(WhetherEnum.NO);
            }
        }

        return frontAgentWithdrawSettleVo;
    }


    @Override
    public void applyWithdraw(ApplyWithdrawVo applyWithdrawVo, Long agentId) {
        List<AgentRebate> agentRebateList = agentRebateMapper.withdrawRebate(agentId, null);
        List<AgentBonus> bonusList = agentBonusMapper.withdrawBonus(agentId, null);
        for (AgentRebate agentRebate : agentRebateList) {
            AgentRebate agentRebate1 = new AgentRebate();
            agentRebate1.setId(agentRebate.getId());
            agentRebate1.setIsPay(IsPayEnum.STATUS1.getValue());
        }
        for (AgentBonus agentBonus : bonusList) {
            AgentBonus agentBonus1 = new AgentBonus();
            agentBonus1.setId(agentBonus.getId());
            agentBonus1.setIsPay(IsPayEnum.STATUS1.getValue());
        }
        FrontAgentWithdrawSettleVo frontAgentWithdrawSettleVo = withdrawInfo(applyWithdrawVo.getCurrentTime(), agentId);
        if (frontAgentWithdrawSettleVo != null) {
            Double withdrawAmount = frontAgentWithdrawSettleVo.getWithdrawAmount();
            AgentWithdraw agentWithdraw = new AgentWithdraw();
            agentWithdraw.setAgentId(agentId);
            agentWithdraw.setAmount(BigDecimal.valueOf(withdrawAmount));
            agentWithdraw.setCreatedTime(new Date());
            save(agentWithdraw);
            agentWithdraw.setPayType(AgentPayTypeEnum.TYPE1.getValue());
            agentWithdraw.setBankCode(applyWithdrawVo.getBankCode());
            agentWithdraw.setBankCard(applyWithdrawVo.getBankCard());
            agentWithdraw.setBankBranch(applyWithdrawVo.getBankBranch());
            agentWithdraw.setCardholder(applyWithdrawVo.getCardholder());
            baseMapper.insert(agentWithdraw);
        }
    }

    @Override
    public HashMap<String, Object> withdrawRecord(Page initMpPage, Long agentId) {
        IPage<WithdrawRecordVo> iPage = baseMapper.withdrawRecord(initMpPage, agentId);
        List<WithdrawRecordVo> withdrawRecordVos = baseMapper.withdrawRecord(agentId);
        Double totalAmount = 0.0;
        for (WithdrawRecordVo withdrawRecordVo : withdrawRecordVos) {
            totalAmount += withdrawRecordVo.getAmount();
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("record", iPage);
        map.put("totalAmount", totalAmount);
        return map;
    }

    @Override
    public HashMap<String, Object> withdrawRecord(Page initMpPage) {
        return null;
    }

    @Override
    public List<String> selectBankHistory(Long agentId) {
        return baseMapper.selectBankHistory(agentId);
    }

    /*
     * 后台保存代理商提现
     *
     *
     * */
    @Override
    public void save(AgentWithdrawDto dto, SysAuth sysAuth) {
        List<AgentRebate> ttList = agentRebateService.list(new QueryWrapper<AgentRebate>().isNull("out_bill_id").eq("agent_id", dto.getAgentId()));
        List<BigDecimal> bougAmoutList = ttList.stream().map(AgentRebate::getRebateAmount).collect(Collectors.toList());
        double sum = bougAmoutList.stream().mapToDouble(x -> x.doubleValue()).sum();
        AgentWithdraw entity=new AgentWithdraw();
        BeanUtils.copyProperties(dto,entity);
        BigDecimal bg = new BigDecimal(sum).setScale(2, RoundingMode.UP);

        entity.setAmount(bg);
        entity.setPayStatus(com.weixing.mall.base.enums.WhetherEnum.NO.getValue());
        entity.setAuditResult(AgentWithdrawAuditEnum.TO_AUDIT.getValue());
        entity.setApplyType(ApplyEnum.TYPE1.getValue());
        entity.setPayType(AgentPayTypeEnum.TYPE1.getValue());
         save(entity);
         //更新返利订单
        UpdateWrapper<AgentRebate> ew = new UpdateWrapper<>();
        ew.lambda().set(AgentRebate::getOperationId, sysAuth.getUid())
                .set(AgentRebate::getOpertaionName, sysAuth.getRealName())
                .set(AgentRebate::getOperationStatus, AgentWithdrawAuditEnum.TO_AUDIT.getValue())
                .set(AgentRebate::getOperationTime, LocalDate.now())
                .set(AgentRebate::getOutBillId,entity.getId() )
                .isNull(AgentRebate::getOutBillId).eq(AgentRebate::getAgentId,entity.getAgentId());
        agentRebateService.update(ew);

    }
}
